﻿using System;
using System.Reflection;

namespace Vbyte.Extension
{
    public static class ReflectExtension
    {
        /// <summary>
        /// 获取堆栈中最底层触发的异常
        /// </summary>
        /// <param name="exp">当前异常</param>
        /// <returns></returns>
        public static Exception GetTriggerException(this Exception exp)
        {
            while (exp.InnerException != null)
            {
                exp = exp.InnerException;
            }
            return exp;
        }
        
        /// <summary>
        /// 判定某成员信息是否包含特定属性的配置
        /// </summary>
        /// <param name="mInfo">成员属性实例</param>
        /// <param name="AttrType">自定义属性类型</param>
        /// <param name="inherit">是否从集成对象中查找</param>
        /// <returns>是否存在特定属性的配置</returns>
        public static bool HasAttribute(this MemberInfo mInfo, Type AttrType, bool inherit)
        {
            object[] attrs = mInfo.GetCustomAttributes(AttrType, inherit);
            return (attrs != null && attrs.Length > 0);
        }

        /// <summary>
        /// 判定某实例类型是否有指定属性的配置
        /// </summary>
        /// <param name="instanceType">实例类型</param>
        /// <param name="AttrType">自定义属性类型</param>
        /// <param name="inherit">是否从集成对象中查找</param>
        /// <returns>是否存在特定属性的配置</returns>
        public static bool HasAttribute(this Type instanceType, Type AttrType, bool inherit)
        {
            object[] attrs = instanceType.GetCustomAttributes(AttrType, inherit);
            return (attrs != null && attrs.Length > 0);
        }

        /// <summary>
        /// 获取某成员信息的特定属性的配置
        /// </summary>
        /// <typeparam name="T">自定义属性类型</typeparam>
        /// <param name="mInfo">成员属性实例</param>
        /// <param name="inherit">是否从集成对象中查找</param>
        /// <returns>如果不存在则放回空数组</returns>
        public static T[] GetMemberInfoCustomAttributes<T>(this MemberInfo mInfo, bool inherit)
        {
            object[] attrs = mInfo.GetCustomAttributes(typeof(T), inherit);
            if (attrs != null && attrs.Length > 0)
            {
                return Array.ConvertAll<object, T>(attrs, new Converter<object, T>(delegate(object o)
                {
                    return (T)o;
                }));
            }
            else
            {
                return new T[0];
            }
        }

        /// <summary>
        /// 检查实例类型是否实现某接口
        /// </summary>
        /// <param name="instanceType">实例类型</param>
        /// <param name="interfaceType">接口类型，对于泛型则为泛型的重整名称类型。</param>
        /// <returns>是否实现了指定类型的接口</returns>
        public static bool HasImplementInterface(this Type instanceType, Type interfaceType)
        {
            return instanceType.GetInterface(interfaceType.FullName) != null;
        }



        /// <summary>
        /// 获取某实例类型的指定属性的配置
        /// </summary>
        /// <typeparam name="T">自定义属性类型</typeparam>
        /// <param name="instanceType">实例类型</param>
        /// <param name="inherit">是否从集成对象中查找</param>
        /// <returns>如果不存在则放回空数组</returns>
        public static T[] GetInstanceCustomAttributes<T>(this Type instanceType, bool inherit)
        {
            object[] attrs = instanceType.GetCustomAttributes(typeof(T), inherit);
            if (attrs != null && attrs.Length > 0)
            {
                return Array.ConvertAll<object, T>(attrs, new Converter<object, T>(delegate(object o)
                {
                    return (T)o;
                }));
            }
            else
            {
                return new T[0];
            }
        } 

    }
}
